package cn.lili.modules.grab.haiguan;

import cn.lili.common.utils.HttpUtils;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.constant.CommonConstant;
import cn.lili.modules.goods.entity.dos.FreeOrderLog;
import cn.lili.modules.goods.service.FreeOrderLogService;
import cn.lili.modules.grab.GrabOrderParam;
import cn.lili.modules.grab.enums.SourceEnums;
import cn.lili.modules.grab.enums.StatusEnums;
import cn.lili.modules.grab.factory.order.GrabOrderService;
import cn.lili.modules.grab.haiguan.service.IFreeWarehouse;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.entity.constant.FreeWarehouseConstant;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.vo.warehouse.ShopSalesOrderReq;
import cn.lili.modules.order.order.entity.vo.warehouse.ShopSalesOrderRes;
import cn.lili.modules.order.order.entity.vo.warehouse.customs.UploadCEBMessageRequest;
import cn.lili.modules.payment.wechat.enums.WechatApiEnum;
import cn.lili.modules.payment.wechat.enums.WechatDomain;
import cn.lili.modules.system.client.SettingClient;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.util.*;

@Component
@Slf4j
public class GrabHaiGuanOrderServiceImpl implements GrabOrderService {

    @Resource
    private IFreeWarehouse freeWarehouse;
    @Resource
    private OrderClient orderClient;
    @Resource
    private FreeOrderLogService freeOrderLogService;
    @Resource
    private SettingClient settingClient;

    @Override
    public SourceEnums step() {
        return SourceEnums.HAIGUAN_ORDER;
    }

    /**
     * 创建订单
     *
     * @param grabParam 参数
     */
    @SneakyThrows
    @Override
    public ResultMessage<Object> createOrder(GrabOrderParam grabParam) {
        log.info("保税仓--创建订单入参----{}", JSONObject.toJSONString(grabParam));
        FreeOrderLog freeOrderLog = new FreeOrderLog();
        FreeOrderLog haiGuanOrderLog = new FreeOrderLog();

        try {
            //通知保税仓出仓库
            ShopSalesOrderReq shopSalesOrderReq = freeWarehouse.shopSalesOrderCreate(grabParam.getOrder(), grabParam.getOrderItems());
            log.info("send begin data == {}", JSONObject.toJSONString(shopSalesOrderReq));
            JSONObject warehouseJson = freeWarehouse.sendHttpRequest(FreeWarehouseConstant.SHOP_SALES_ORDER_CREATE, shopSalesOrderReq);
            ObjectMapper mapper = new ObjectMapper();
            if (warehouseJson.getInteger("resultCode") == 1) {
                ShopSalesOrderRes res = mapper.readValue(warehouseJson.getJSONObject("resultData").toJSONString(), ShopSalesOrderRes.class);
                log.info("ShopSalesOrderRes == {} ", JSONObject.toJSONString(res));
                log.info("上传保税仓 成功 == {}", grabParam.getOrder().getSn());
                Order order = new Order();
                order.setTrackingNo(res.getTrackingNo());
                order.setSn(grabParam.getOrder().getSn());
                orderClient.update(order);
            } else {
                Order order = new Order();
                order.setSn(grabParam.getOrder().getSn());
                order.setFreeErrorMessage(warehouseJson.getString("resultContent"));
                orderClient.update(order);
                freeOrderLog.setStatusType(CommonConstant.STATUS_TYPE_02);
                freeOrderLog.setPlatformType(CommonConstant.PLATFORM_TYPE_01);
                freeOrderLog.setReturnMessage(warehouseJson.toJSONString());
                freeOrderLog.setSendMessage(JSONObject.toJSONString(shopSalesOrderReq));
                freeOrderLog.setOutTradeNo(shopSalesOrderReq.getOrderNo());
                freeOrderLog.setOrderSn(grabParam.getOrder().getSn());
                freeOrderLogService.save(freeOrderLog);
            }
            log.info("warehouseJson == {}", JSONObject.toJSONString(warehouseJson));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上报保税仓失败", e);
        }

        try {
            //上报海关
            UploadCEBMessageRequest uploadCEBMessageRequest = freeWarehouse.uploadCEBMessage(grabParam.getOrder(), grabParam.getOrderItems());
            log.info("uploadCEBMessageRequest == {}", JSONObject.toJSONString(uploadCEBMessageRequest));
            JSONObject uploadRes = freeWarehouse.sendCustomsRequest(FreeWarehouseConstant.UPLOAD_MESSAGE, uploadCEBMessageRequest);
            log.info("uploadRes == {}", JSONObject.toJSONString(uploadRes));

            //接收海关回应
            JSONObject receiveJson = freeWarehouse.sendCustomsRequest(FreeWarehouseConstant.RECEIVE_MESSAGE, null);
            log.info("receiveJson == {}", receiveJson);
            //成功
            if (receiveJson.getInteger("code") >= 0) {
                log.info("上传海关 成功 == {}", grabParam.getOrder().getSn());
            } else {
                haiGuanOrderLog.setStatusType(CommonConstant.STATUS_TYPE_02);
                haiGuanOrderLog.setPlatformType(CommonConstant.PLATFORM_TYPE_02);
                haiGuanOrderLog.setOutTradeNo(grabParam.getOrder().getOutTradeNo());
                haiGuanOrderLog.setOrderSn(grabParam.getOrder().getSn());
                haiGuanOrderLog.setSendMessage(JSONObject.toJSONString(uploadCEBMessageRequest));
                haiGuanOrderLog.setReturnMessage(receiveJson.toJSONString());
                freeOrderLogService.save(haiGuanOrderLog);
                String returnInfo = receiveJson.getString("returnInfo");
                Order order = new Order();
                order.setSn(grabParam.getOrder().getSn());
                order.setCustomsErrorMessage(returnInfo);
                orderClient.update(order);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上报海关失败", e);
        }

        try {
            //推送微信清关
            Map<String, String> params = new LinkedHashMap<>();
            params.put("appid", "wx0ab9cf8ee8dfda5e");
            params.put("customs", "GUANGZHOU_ZS");
            params.put("mch_customs_no", "460168002H");
            params.put("mch_id", "1670029219");
            params.put("out_trade_no", grabParam.getOrder().getOutTradeNo());
            params.put("transaction_id", grabParam.getOrder().getTransactionId());
//        params.put("key", "Lilishopliushuailifenlonggaolei1");
            // 替换为你的密钥
            String key = "uI7wM2eB7mE5yF1aG6fG6kD3zO6wK3fG";

            // 生成签名
            String sign = generateSign(params, key);
            System.out.println("生成的签名：" + sign);
            // 验证签名
            boolean isValid = verifySign(params, key, sign);
            System.out.println("校验结果：" + (isValid ? "通过" : "不通过"));
            params.put("sign", sign);
            //请求参数
            String body = mapToXML(params);
            System.out.println("body = " + body);
            String string = HttpUtils.doPostWithJson(WechatDomain.CHINA.toString() + WechatApiEnum.CLEARANCE.toString(), body);
            System.out.println("string = " + string);

            //查询微信清关信息
            Map<String, String> customsClearanceInformationParams = new LinkedHashMap<>();
            customsClearanceInformationParams.put("appid", "wx0ab9cf8ee8dfda5e");
            customsClearanceInformationParams.put("customs", "GUANGZHOU_ZS");
            customsClearanceInformationParams.put("mch_id", "1670029219");
            customsClearanceInformationParams.put("transaction_id", grabParam.getOrder().getTransactionId());
            // 生成签名
            String customsClearanceInformationSign = generateSign(customsClearanceInformationParams, key);
            System.out.println("生成的签名：" + customsClearanceInformationSign);
            // 验证签名
            boolean customsClearanceInformationIsValid = verifySign(customsClearanceInformationParams, key, customsClearanceInformationSign);
            System.out.println("校验结果：" + (customsClearanceInformationIsValid ? "通过" : "不通过"));
            customsClearanceInformationParams.put("sign", customsClearanceInformationSign);
            //请求参数
            String customsClearanceInformationBody = mapToXML(customsClearanceInformationParams);
            System.out.println("body = " + customsClearanceInformationBody);
            String customsClearanceInformationString = HttpUtils.doPostWithJson(WechatDomain.CHINA.toString() + WechatApiEnum.CLEARANCE_QUERY.toString(), customsClearanceInformationBody);
            System.out.println("customsClearanceInformationString = " + customsClearanceInformationString);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("推送微信清关失败", e);
        }

        return ResultUtil.data(StatusEnums.STATUS_200.getDes());
    }


    //推送，清关信息
//    public static void main(String[] args) {
////        // 给定参数和密钥
//        Map<String, String> params = new LinkedHashMap<>();
//        params.put("appid", "wx0ab9cf8ee8dfda5e");
//        params.put("customs", "GUANGZHOU_ZS");
//        params.put("mch_customs_no", "460168002H");
//        params.put("mch_id", "1670029219");
//        params.put("out_trade_no", "1782951593071390720");
//        params.put("transaction_id", "4200002187202404243984791948");
////        params.put("key", "Lilishopliushuailifenlonggaolei1");
//        String key = "uI7wM2eB7mE5yF1aG6fG6kD3zO6wK3fG"; // 替换为你的密钥
//        // 生成签名
//        String sign = generateSign(params, key);
//        System.out.println("生成的签名：" + sign);
//        // 验证签名
//        boolean isValid = verifySign(params, key, sign);
//        System.out.println("校验结果：" + (isValid ? "通过" : "不通过"));
//        params.put("sign", sign);
//        //请求参数
//        String body = mapToXML(params);
//        System.out.println("body = " + body);
//        String string = HttpUtils.doPostWithJson(WechatDomain.CHINA.toString() + WechatApiEnum.CLEARANCE.toString(), body);
//        System.out.println("string = " + string);
//    }

    //查询清关信息
    public static void main(String[] args) {
        // 给定参数和密钥
        Map<String, String> params = new LinkedHashMap<>();
        params.put("appid", "wx0ab9cf8ee8dfda5e");
        params.put("customs", "GUANGZHOU_ZS");
        params.put("mch_id", "1670029219");
        params.put("out_trade_no", "1784773981228810240");
        String key = "uI7wM2eB7mE5yF1aG6fG6kD3zO6wK3fG"; // 替换为你的密钥
        // 生成签名
        String sign = generateSign(params, key);
        System.out.println("生成的签名：" + sign);
        // 验证签名
        boolean isValid = verifySign(params, key, sign);
        System.out.println("校验结果：" + (isValid ? "通过" : "不通过"));
        params.put("sign", sign);
        //请求参数
        String body = mapToXML(params);
        System.out.println("body = " + body);
        String string = HttpUtils.doPostWithJson(WechatDomain.CHINA.toString() + WechatApiEnum.CLEARANCE_QUERY.toString(), body);
        System.out.println("string = " + string);
    }


    //上报海关179接口
//    public static void main(String[] args) {
//
//        UploadCEBMessageRequest uploadCEBMessageRequest = freeWarehouse.uploadCEBMessage(grabParam.getOrder(), grabParam.getOrderItems());
//        log.info("uploadCEBMessageRequest == {}", JSONObject.toJSONString(uploadCEBMessageRequest));
//        JSONObject uploadRes = freeWarehouse.sendCustomsRequest(FreeWarehouseConstant.UPLOAD_MESSAGE, uploadCEBMessageRequest);
//        log.info("uploadRes == {}", JSONObject.toJSONString(uploadRes));
//    }

    // 将 Map 转换为 XML 字符串
    public static String mapToXML(Map<String, String> map) {
        StringBuilder xml = new StringBuilder();
        xml.append("<xml>");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            xml.append("<").append(entry.getKey()).append(">").append(entry.getValue()).append("</").append(entry.getKey()).append(">");
        }
        xml.append("</xml>");
        return xml.toString();
    }


    // 生成签名
    public static String generateSign(Map<String, String> params, String key) {
        // 对参数按照key=value的格式，并按照参数名ASCII字典序排序生成字符串
        StringBuilder sb = new StringBuilder();
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        for (String k : keys) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(k).append("=").append(params.get(k));
        }
        // 连接密钥key
        sb.append("&key=").append(key);
        // 生成sign并转成大写
        return md5(sb.toString()).toUpperCase();
    }

    // 校验签名
    public static boolean verifySign(Map<String, String> params, String key, String sign) {
        // 重新生成签名
        String generatedSign = generateSign(params, key);
        // 比较原签名值和新签名值是否相同
        return generatedSign.equals(sign);
    }

    // MD5加密（实际应用中使用更安全的加密算法）
    private static String md5(String input) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] array = md.digest(input.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte b : array) {
                sb.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException | java.io.UnsupportedEncodingException e) {
            return null;
        }
    }

}
